package com.example.springboot08shiro2.config;

import com.example.springboot08shiro2.pojo.User;
import com.example.springboot08shiro2.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 自定义的Realm, 只需要继承一下就行
 * 在ShiroConfig.java中注册, 会被添加到spring容器中
 */
public class UserRealm extends AuthorizingRealm {
    //要从数据库中拿名称和密码
    @Autowired
    UserService userService;
    //授权, 每次登录后访问被限定授权的url时, 会执行一次这个授权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("执行了授权=>doGetAuthorizationInfo");
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        //这里给每个人添加一个权限, 权限应该从数据库中读取
        //info.addStringPermission("user:add");
        //拿到当前登录的对象
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User)subject.getPrincipal();
        //设置当前业务的权限
        info.addStringPermission(currentUser.getPerms());
        return info;
    }
    //认证, 每次登录的时候会执行一次这个方法
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("执行了认证=>doGetAuthenticationInfo");
        //用户名, 密码, 应该从数据库中取
//        String name = "root";
//        String password = "123456";
        //?token是前端传过来的?前端封装好了?
        UsernamePasswordToken userToken = (UsernamePasswordToken)token;
        //连接真实数据库
        User user = userService.queryUserByName(userToken.getUsername());
        if(user==null){
            return null;//会在调用放那里被判定为异常, 用户名不存在
        }
        //传一个session, 让前端知道已经登录了, 做一些判断用。
        Subject currentSubject = SecurityUtils.getSubject();
        Session session = currentSubject.getSession();
        session.setAttribute("loginUser", user);
        //密码认证由shiro本身做, 明文密码, 可以加密, 可以用md5加密或者md5盐值加密
        return new SimpleAuthenticationInfo(user, user.getPwd(), "");
    }
}
